package com.ticket.web.controller.yanchu;

import java.math.BigDecimal;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ticket.common.constant.PerformConstants;
import com.ticket.common.exception.ServiceException;
import com.ticket.system.domain.vo.CancelTicketStatVo;
import com.ticket.system.domain.vo.RefundOrderVo;
import io.swagger.annotations.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ticket.common.annotation.Log;
import com.ticket.common.core.controller.BaseController;
import com.ticket.common.core.domain.AjaxResult;
import com.ticket.common.enums.BusinessType;
import com.ticket.system.domain.YanchuRefundOrder;
import com.ticket.system.service.IYanchuRefundOrderService;
import com.ticket.common.utils.poi.ExcelUtil;
import com.ticket.common.core.page.TableDataInfo;

/**
 * 退款单Controller
 * 
 * @author ruoyi
 * @date 2023-10-31
 */
@Api(description = "退票管理")
@RestController
@RequestMapping("/system/orderRefund")
public class YanchuRefundOrderController extends BaseController
{
    @Autowired
    private IYanchuRefundOrderService yanchuRefundOrderService;

    @Resource
    private WxPayService wxPayService;

    /**
     * 查询退款单列表
     */
    @PreAuthorize("@ss.hasPermi('system:orderRefund:list')")
    @GetMapping("/list")
    @ApiOperation("查询退款单列表")
    @ApiImplicitParam(name = "yanchuRefundOrder", value = "退款单对象", dataType = "YanchuRefundOrder", dataTypeClass = YanchuRefundOrder.class)
    public TableDataInfo list(YanchuRefundOrder yanchuRefundOrder)
    {
        startPage();
        List<RefundOrderVo> list = yanchuRefundOrderService.selectYanchuRefundOrderList(yanchuRefundOrder);
        return getDataTable(list);
    }

    /**
     * 退款单支付补偿
     */
    @ApiOperation("退款单支付补偿")
    @ApiImplicitParam(name = "refundNo", value = "退款单号", dataType = "String", dataTypeClass = String.class)
    @GetMapping(value = "/orderRefundInfo")
    public AjaxResult orderRefundInfo(@RequestParam(name = "refundNo")String refundNo)
    {
        try {
            return success(yanchuRefundOrderService.selectRefundPayByRefundNo(refundNo));
        }catch (Exception e){
            logger.error("orderRefundInfo error",e);
            return error();
        }
    }

    /**
     * 导出退款单列表
     */
    @PreAuthorize("@ss.hasPermi('system:order:export')")
    @Log(title = "退款单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, YanchuRefundOrder yanchuRefundOrder,String[] propes)
    {
        List<RefundOrderVo> list = yanchuRefundOrderService.selectYanchuRefundOrderList(yanchuRefundOrder);
        ExcelUtil<RefundOrderVo> util = new ExcelUtil<RefundOrderVo>(RefundOrderVo.class);
        util.exportExcel(response, list, "退款单数据");
    }

    /**
     * 获取退款单详细信息
     */
    @ApiOperation(value = "获取退款单详细信息")
    @ApiImplicitParam(name = "id", value = "退款单编码", dataType = "Long", dataTypeClass = Long.class)
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "退款单扩展对象",response = RefundOrderVo.class)
    })
    @GetMapping(value = "/{id}",produces = {"application/json"})
    public AjaxResult<RefundOrderVo> getInfo(@PathVariable("id") Long id)
    {
        return success(yanchuRefundOrderService.selectRefundOrderVoById(id));
    }

    /**
     * 根绝详情id获取退款单详细信息
     */
    @ApiOperation(value = "根绝详情id获取退款单详细信息")
    @ApiImplicitParam(name = "idDetail", value = "详情编码", dataType = "Long", dataTypeClass = Long.class)
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "退款单扩展对象",response = RefundOrderVo.class)
    })
    @GetMapping(value = "/detailById",produces = {"application/json"})
    public AjaxResult<RefundOrderVo> detailById(Long id)
    {
        return success(yanchuRefundOrderService.selectRefundOrderVoByDetailId(id));
    }

    /**
     * 新增退款单
     */
    @ApiOperation("新增退款单")
    @ApiImplicitParam(name = "yanchuRefundOrder", value = "退款单对象", dataType = "YanchuRefundOrder", dataTypeClass = YanchuRefundOrder.class)
    @PreAuthorize("@ss.hasPermi('system:orderRefund:add')")
    @Log(title = "退款单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody @Valid YanchuRefundOrder yanchuRefundOrder)
    {
        try {
            return toAjax(yanchuRefundOrderService.insertYanchuRefundOrder(yanchuRefundOrder,null));
        }catch(ServiceException se){
            logger.error("新增退款单ServiceException",se);
            return AjaxResult.error(se.getMessage());
        }
        catch (Exception e){
            logger.error("新增退款单失败",e);
            return AjaxResult.error("新增退款单失败");
        }
    }

    /**
     * 修改退款单
     */
    @PreAuthorize("@ss.hasPermi('system:orderRefund:edit')")
    @Log(title = "退款单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody YanchuRefundOrder yanchuRefundOrder)
    {
        return toAjax(yanchuRefundOrderService.updateYanchuRefundOrder(yanchuRefundOrder));
    }

    /**
     * 删除退款单
     */
    @PreAuthorize("@ss.hasPermi('system:orderRefund:remove')")
    @Log(title = "退款单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(yanchuRefundOrderService.deleteYanchuRefundOrderByIds(ids));
    }

    /**
     * 整单退款回调
     * @param xmlData
     * @return
     */
    @Log(title = "整单退款回调", businessType = BusinessType.UPDATE)
    @RequestMapping(value = "/refundNotify/forAllUser",method = {RequestMethod.GET,RequestMethod.POST})
    public String refundNotify(@RequestBody String xmlData) {
        WxPayRefundNotifyResult wxPayRefundNotifyResult;
        try {
            wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
        } catch (Exception e) {
            logger.error("退款失败，失败信息:{}", e);
            return WxPayNotifyResponse.fail("退款失败");
        }
        //判断你返回状态信息是否正确
        if (PerformConstants.REFUND_SUCCESS.equals(wxPayRefundNotifyResult.getReturnCode())) {
            WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
            //判断退款状态
            if (PerformConstants.REFUND_SUCCESS.equals(reqInfo.getRefundStatus())) {
                //内部订单号
                String outTradeNo = reqInfo.getOutTradeNo();
                String refundNo = reqInfo.getOutRefundNo();
                Integer refundFee = reqInfo.getRefundFee();
                yanchuRefundOrderService.cancelOrderNotify(outTradeNo,refundNo, BaseWxPayRequest.fen2Yuan(BigDecimal.valueOf(refundFee)));
                return WxPayNotifyResponse.success("退款成功！");
            }
        }
        return WxPayNotifyResponse.fail("回调有误!");
    }

    /**
     * 部分退款回调
     * @param xmlData
     * @return
     */
    @Log(title = "部分退款回调", businessType = BusinessType.UPDATE)
    @RequestMapping(value = "/refundTicketNotify/forAllUser",method = {RequestMethod.GET,RequestMethod.POST})
    public String refundTicketNotify(@RequestBody String xmlData) {
        WxPayRefundNotifyResult wxPayRefundNotifyResult;
        try {
            wxPayRefundNotifyResult = wxPayService.parseRefundNotifyResult(xmlData);
        } catch (Exception e) {
            logger.error("退款失败，失败信息:{}", e);
            return WxPayNotifyResponse.fail("退款失败");
        }
        //判断你返回状态信息是否正确
        if (PerformConstants.REFUND_SUCCESS.equals(wxPayRefundNotifyResult.getReturnCode())) {
            WxPayRefundNotifyResult.ReqInfo reqInfo = wxPayRefundNotifyResult.getReqInfo();
            //判断退款状态
            if (PerformConstants.REFUND_SUCCESS.equals(reqInfo.getRefundStatus())) {
                //内部订单号
                String outRefundNo = reqInfo.getOutRefundNo();
                Integer refundFee = reqInfo.getRefundFee();
                yanchuRefundOrderService.cancelTicketOrderNotify(outRefundNo, BaseWxPayRequest.fen2Yuan(BigDecimal.valueOf(refundFee)));
                return WxPayNotifyResponse.success("退款成功！");
            }
        }
        return WxPayNotifyResponse.fail("回调有误!");
    }
    /**
     * 退款统计
     * @param sessionId
     * @return
     */
    @ApiOperation("退票统计")
    @ApiImplicitParam(name = "sessionId", value = "场次编号", dataType = "Long", dataTypeClass = Long.class)
    @GetMapping(value = "/cancelTicketStat")
    public CancelTicketStatVo cancelTicketStat(@RequestParam Long sessionId) {
        return yanchuRefundOrderService.cancelTicketStat(sessionId);
    }


    @ApiOperation("管理端导出退单列表")
    @PreAuthorize("@ss.hasPermi('system:detail:export')")
    @Log(title = "导出退单列表", businessType = BusinessType.EXPORT)
    @PostMapping("/exportRefundOrderList")
    public void exportRefundOrderList(HttpServletResponse response, YanchuRefundOrder yanchuRefundOrder) {
        yanchuRefundOrderService.exportRefundOrderList(response, yanchuRefundOrder);
    }

    @ApiOperation("管理端根据条件得出退款导出条数")
    @PreAuthorize("@ss.hasPermi('system:detail:export')")
    @PostMapping("/getExportCount")
    public AjaxResult getExportCount(YanchuRefundOrder yanchuRefundOrder) {
        return AjaxResult.success(yanchuRefundOrderService.getExportCount(yanchuRefundOrder));
    }
}
